﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using BibMan.model.database.bibtex;
using System.IO;

namespace BibMan.model.database.Referencer {
    [Serializable]
    [XmlType("doc")]
    public class JabDoc : JabRefItem {

        [XmlElement("filename")]
        public String Filename { get; set; }

        [XmlElement("relative_filename")]
        public String RelativeFilename { get; set; }

        [XmlElement("key")]
        public String Id { get; set; }

        [XmlElement("bib_key")]
        public String BibKey { get; set; }

        [XmlElement("notes")]
        public String Notes { get; set; }

        [XmlElement("tagged")]
        public List<String> Tags { get; set; }

        [XmlElement("bib_type")]
        public String BibEntryType { get; set; }

        [XmlElement("bib_overridetype")]
        public String BibItemType { get; set; }

        [XmlElement("bib_dio")]
        public String BibDoi { get; set; }

        [XmlElement("bib_title")]
        public String BibTitle { get; set; }

        [XmlElement("bib_authors")]
        public String BibAuthors { get; set; }

        [XmlElement("bib_editors")]
        public String BibEditors { get; set; }

        [XmlElement("bib_publisher")]
        public String BibPublisher { get; set; }

        [XmlElement("bib_journal")]
        public String BibJournal { get; set; }

        [XmlElement("bib_volume")]
        public String BibVolume { get; set; }

        [XmlElement("bib_number")]
        public String BibNumber { get; set; }

        [XmlElement("bib_pages")]
        public String BibPages { get; set; }

        [XmlElement("bib_year")]
        public String BibYear { get; set; }

        [XmlElement("bib_month")]
        public String BibMonth { get; set; }

        [XmlElement("bib_series")]
        public String BibSeries { get; set; }

        [XmlElement("bib_address")]
        public String BibAddress { get; set; }

        [XmlElement("bib_edition")]
        public String BibEdition { get; set; }

        [XmlElement("bib_howpublished")]
        public String BibHowpublished { get; set; }

        [XmlElement("bib_chapter")]
        public String BibChapter { get; set; }

        [XmlElement("bib_school")]
        public String BibSchool { get; set; }

        [XmlElement("bib_booktitle")]
        public String BibBooktitle { get; set; }

        [XmlElement("bib_organization")]
        public String BibOrganization { get; set; }

        [XmlElement("bib_institution")]
        public String BibInstitution { get; set; }

        [XmlElement("bib_annote")]
        public string BibAnnote { get; set; }

        [XmlElement("bib_crossref")]
        public string BibCrossref { get; set; }

        [XmlElement("bib_eprint")]
        public string BibEprint { get; set; }

        [XmlElement("bib_note")]
        public string BibNote { get; set; }

        [XmlElement("bib_url")]
        public string BibUrl { get; set; }

        [XmlElement("bib_extra")]
        public List<JabBibExtra> BibExtras { get; set; }

        public override string  ToString() {
            StringBuilder ret = new StringBuilder();
            ret.Append(BibTitle);
            return ret.ToString();
        }

        public Reference ToReference(List<JabTag> allTags) {
            Reference ret = new Reference();
            BibType tempType;
            if (!Enum.TryParse<BibType>(BibEntryType, true, out tempType)) {
                tempType = BibType.misc;
            }
            ret.BibItem.BibType = tempType;
            ret.BibItem.Id = Id;
            ret.BibItem.AddTag(TagName.address, BibAddress);
            ret.BibItem.AddTag(TagName.annote, BibAnnote);
            ret.BibItem.AddTag(TagName.author, BibAuthors);
            ret.BibItem.AddTag(TagName.booktitle, BibBooktitle);
            ret.BibItem.AddTag(TagName.chapter, BibChapter);
            ret.BibItem.AddTag(TagName.crossref, BibCrossref);
            ret.BibItem.AddTag(TagName.edition, BibEdition);
            ret.BibItem.AddTag(TagName.editor, BibEditors);
            ret.BibItem.AddTag(TagName.eprint, BibEprint);
            ret.BibItem.AddTag(TagName.howpublished, BibHowpublished);
            ret.BibItem.AddTag(TagName.institution, BibInstitution);
            ret.BibItem.AddTag(TagName.journal, BibJournal);
            ret.BibItem.AddTag(TagName.key, BibKey);
            ret.BibItem.AddTag(TagName.month, BibMonth);
            ret.BibItem.AddTag(TagName.note, BibNote);
            ret.BibItem.AddTag(TagName.number, BibNumber);
            ret.BibItem.AddTag(TagName.organization, BibOrganization);
            ret.BibItem.AddTag(TagName.pages, BibPages);
            ret.BibItem.AddTag(TagName.publisher, BibPublisher);
            ret.BibItem.AddTag(TagName.school, BibSchool);
            ret.BibItem.AddTag(TagName.title, BibTitle);
            ret.BibItem.AddTag(TagName.url, BibUrl);
            ret.BibItem.AddTag(TagName.volume, BibVolume);
            ret.BibItem.AddTag(TagName.year, BibYear);
            ret.BibItem.AddTag("doi", BibDoi);
            foreach (JabBibExtra t in BibExtras) {
                ret.BibItem.AddTag(t.Key, t.Content);
            }

            ret.Notes = Notes;
            foreach (int tagId in Tags.ConvertAll<int>(e => Convert.ToInt32(e))) {
                ret.Pins.Add(allTags[tagId].Name);
            }
            ret.Path = RelativeFilename;
            return ret;
        }
       
    }

}
